package xyz.lilei23.framework.jdbc;

import com.alibaba.druid.pool.DruidDataSource;
import xyz.lilei23.framework.transaction.TransactionManager;
import xyz.lilei23.framework.utils.StringUtils;

import java.sql.Connection;
import java.sql.SQLException;

/**
 * JdbcTransactionManager jbbc事务管理器实现
 * @author lilei
 * @date 31/07/2021 16:20
 * @version 1.0
 **/
public class JdbcTransactionManager implements TransactionManager {

    private DruidDataSource druidDataSource;

    private DataSourceProperties dataSourceProperties;

    public void setDataSourceProperties(DataSourceProperties dataSourceProperties) {
        if (dataSourceProperties==null) {
            throw new RuntimeException("请配置连接信息");
        }
        if (StringUtils.isEmpty(dataSourceProperties.getDriverClassName())){
            throw new RuntimeException("请先配置驱动类");
        }
        if (StringUtils.isEmpty(dataSourceProperties.getPassword())){
            throw new RuntimeException("请配置连接密码");
        }
        if (StringUtils.isEmpty(dataSourceProperties.getUrl())){
            throw new RuntimeException("请配置连接url");
        }
        if (StringUtils.isEmpty(dataSourceProperties.getUserName())){
            throw new RuntimeException("请配置用户名称");
        }
        this.dataSourceProperties = dataSourceProperties;
        DruidDataSource db = new DruidDataSource();
        db.setDriverClassName(dataSourceProperties.getDriverClassName());
        db.setUrl(dataSourceProperties.getUrl());
        db.setPassword(dataSourceProperties.getPassword());
        db.setUsername(dataSourceProperties.getUserName());
        druidDataSource = db;
    }

    public DataSourceProperties getDataSourceProperties() {
        return dataSourceProperties;
    }

    /**
     *  存储当前线程的连接
     */
    private ThreadLocal<Connection> threadLocalConnection = new ThreadLocal<>();

    /**
     * 从当前线程获取连接
     */
    @Override
    public Connection getCurrentThreadConn() throws SQLException {
        // 判断当前线程中是否已经绑定连接，如果没有绑定，需要从连接池获取一个连接绑定到当前线程
        Connection connection = threadLocalConnection.get();
        if(connection == null) {
            // 从连接池拿连接并绑定到线程
            connection = druidDataSource.getConnection();
            // 绑定到当前线程
            threadLocalConnection.set(connection);
        }
        return connection;

    }
    /**
     * 开启手动事务控制
     */
    @Override
    public void beginTransaction() throws SQLException {
        getCurrentThreadConn().setAutoCommit(false);
    }


    /**
     * 提交事务
     */
    @Override
    public void commit() throws SQLException {
        getCurrentThreadConn().commit();
        threadLocalConnection.remove();
    }


    /**
     * 回滚事务
     */
    @Override
    public void rollback() throws SQLException {
        getCurrentThreadConn().rollback();
    }
}
